<!-- 模板部分 -->
<template>
  <view class="page-container">
    <!-- 导航栏 -->
    <view class="nav-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
      <view class="back-button" @tap="goBack">
        <text class="iconfont icon-back"></text>
      </view>
      <view class="title">个人信息</view>
    </view>

    <!-- 加载状态 -->
    <view v-if="loading" class="loading-container">
      <view class="loading-spinner"></view>
      <text class="loading-text">加载中...</text>
    </view>

    <!-- 用户基本信息 -->
    <view v-else class="user-info">
      <view class="decoration-bg"></view>
      <button class="avatar-button" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
        <image class="avatar" :src="userInfo.avatar || '/static/images/default-avatar.png'" mode="aspectFill" />
      </button>
      
      <!-- 昵称编辑 -->
      <view class="nickname-container" @tap="startEditingNickname">
        <text v-if="!isEditingNickname" class="nickname">
          {{ userInfo.nickname || '未设置昵称' }}
        </text>
        <input
          v-else
          class="nickname-input"
          type="text"
          v-model="tempNickname"
          @blur="saveNickname"
          @confirm="saveNickname"
          auto-focus
        />
      </view>
      
      <!-- 新的VIP卡片设计 -->
        <view class="new-vip-card" @tap="goToMemberCenter">
          <view class="left-section">
            <view class="icon-container">
              <image class="vip-icon" src="/static/images/vip-pattern.png" />
            </view>
            <view class="text-content">
              <text class="main-title">开通会员</text>
              <text class="sub-title">享优先体验高级AI模型、无限畅聊、专属客服</text>
            </view>
          </view>
          <view class="right-section">
            <text class="action-button">首月仅￥9</text>
          </view>
        </view>
    </view>

    <!-- 信息列表 -->
    <view class="info-section">
      <view class="section-title">账号信息</view>
      <view class="info-list">
        <view class="info-item">
          <text class="label">UUID</text>
          <view class="value-with-copy">
            <text class="value uuid">{{ formattedUUID }}</text>
            <text class="copy-btn" @tap="copyUUID">复制</text>
          </view>
        </view>
        
        <view class="info-item">
          <text class="label">手机号</text>
          <text class="value">{{ formattedPhone }}</text>
          <text class="action" @tap="bindPhone" v-if="!userInfo.phone">绑定</text>
        </view>
        
        <view class="info-item">
          <text class="label">邮箱</text>
          <view class="email-container" @tap="startEditingEmail" v-if="userInfo.email && !isEditingEmail">
            <text class="value">{{ userInfo.email }}</text>
          </view>
          <input
            v-else-if="isEditingEmail"
            class="email-input"
            type="text"
            v-model="tempEmail"
            @blur="saveEmail"
            @confirm="saveEmail"
            auto-focus
          />
          <text class="value" v-else>未绑定</text>
          <text class="action" @tap="bindEmail" v-if="!userInfo.email">绑定</text>
        </view>
      </view>
    </view>
	
	<!-- 会员信息 - 如果是VIP用户 -->
	<view class="vip-section" v-if="isVip">
	  <view class="section-title">会员信息</view>
	  <view class="vip-card">
	    <view class="vip-info">
	      <text class="vip-label">会员类型</text>
	      <text class="vip-value">高级AI模型VIP {{ vipInfo?.subscriptionTypeText || '' }}</text>
	    </view>
	    <view class="vip-info">
	      <text class="vip-label">到期时间</text>
	      <text class="vip-value">{{ formattedVipExpireTime }}</text>
	    </view>
	  </view>
	</view>

    <!-- Token使用情况 -->
    <view class="token-section">
      <view class="decoration-bg"></view>
      <view class="section-title">
        <text>Token使用情况</text>
        <text class="refresh-btn" @tap="refreshTokenUsage">刷新</text>
      </view>
      
      <view class="token-card">
        <view class="token-item">
          <text class="token-label">已使用</text>
          <text class="token-value">{{ formattedTokensUsed }}</text>
        </view>
        <view class="token-item">
          <text class="token-label">待消费</text>
          <text class="token-value">{{ formattedTokensBalance }}</text>
        </view>
      </view>
      
      <!-- Token使用进度条 -->
      <view class="token-progress">
        <view class="progress-bar">
          <view 
            class="progress-inner" 
            :style="{width: tokenPercentage + '%', backgroundColor: tokenPercentageColor}"
          ></view>
        </view>
        <text class="progress-text">{{ tokenPercentage }}%</text>
      </view>
    </view>
    
    <!-- 退出登录按钮 -->
    <button class="logout-button" @tap="handleLogout">退出登录</button>

    <!-- 底部导航栏 -->
    <view class="fixed-footer">
      <TabBar :current-tab="3" />
    </view>
  </view>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useUserStore } from '@/stores'
import { system, token } from '@/utils'
import api from '@/api/modules'
import TabBar from '@/components/TabBar/TabBar.vue'

// 状态管理
const userStore = useUserStore()
const statusBarHeight = ref(system.getDeviceInfo().statusBarHeight || 0)
const loading = ref(true)
const isEditingNickname = ref(false)
const isEditingEmail = ref(false)
const tempNickname = ref('')
const tempEmail = ref('')
const vipInfo = ref(null)
const isPayLoading = ref(false)
const orderId = ref('')
const orderType = ref('')

// 路由变化监听
const setupRouteWatcher = () => {
  const pages = getCurrentPages();
  const currentPage = pages[pages.length - 1];
  
  if (currentPage) {
    const onShowHandler = () => {
      // 检查是否需要刷新数据（登录后的首次访问）
      const needRefresh = uni.getStorageSync('needDataRefresh');
      
      // 页面标识，用于记录哪些页面已刷新
      const pageKey = 'refreshed_' + currentPage.route;
      const pageRefreshed = uni.getStorageSync(pageKey);
      
      // 如果是登录后且该页面还未刷新，则加载数据
      if (needRefresh === 'true' && !pageRefreshed) {
        console.log('登录后首次访问页面，刷新数据');
        refreshAllPageData();
        
        // 标记此页面已刷新
        uni.setStorageSync(pageKey, 'true');
        
        // 检查是否所有主要页面都已刷新
        const mainPages = [
          'refreshed_pages/my/my',
          'refreshed_pages/index/index',
          'refreshed_pages/discover/discover',
          'refreshed_pages/device-manage/device-manage'
        ];
        
        // 如果所有页面都已刷新，清除全局刷新标记
        if (mainPages.every(key => uni.getStorageSync(key))) {
          uni.setStorageSync('needDataRefresh', 'false');
        }
      }
    };
    
    // 添加页面显示事件监听
    currentPage.onShow = function() {
      onShowHandler();
      if (this.$mp && this.$mp.page && this.$mp.page._onShow) {
        this.$mp.page._onShow();
      }
    };
  }
};

// 切换标签页
const switchTab = (index) => {
  const routes = [
    '/pages/index/index',
    '/pages/discover/discover',
    '/pages/my/my'
  ]
  uni.switchTab({
    url: routes[index]
  })
}

// 计算属性 - 用户信息
const userInfo = computed(() => {
  return userStore.userInfo || {
    username: '',
    uuid: '',
    avatar: '',
    phone: '',
    email: '',
    createdAt: '',
    registerSource: '',
    dailyTokensLimit: 0,
    totalTokensUsed: 0,
    totalTokensBalance: 0,
    vipStatus: 0
  }
})

// 格式化计算属性
const formattedUUID = computed(() => formatUUID(userInfo.value.uuid))
const formattedPhone = computed(() => formatPhone(userInfo.value.phone))
const formattedTokensUsed = computed(() => formatNumber(userInfo.value.totalTokensUsed || 0))
const formattedTokensBalance = computed(() => formatNumber(userInfo.value.totalTokensBalance || 0))
const formattedVipExpireTime = computed(() => formatDate(vipInfo.value?.expireTime) || '永久')
const isVip = computed(() => userInfo.value?.vipStatus === 1)

// Token进度相关计算属性
const tokenPercentage = computed(() => {
  const totalUsed = userInfo.value.totalTokensUsed || 0
  const totalBalance = userInfo.value.totalTokensBalance || 1
  const total = totalUsed + totalBalance
  return Math.min(Math.round((totalUsed / total) * 100), 100)
})

const tokenPercentageColor = computed(() => {
  if (tokenPercentage.value < 50) return '#5677fc'
  if (tokenPercentage.value < 80) return '#FFA500'
  return '#FF4D4F'
})

// 监听登录状态变化事件
const setupLoginListener = () => {
  uni.$on('loginStateChanged', (data) => {
    console.log('个人信息页面检测到登录状态变化，强制刷新数据');
    // 清除用户数据缓存
    userStore.lastRefreshTime = 0;
    // 强制刷新所有页面数据
    refreshAllPageData();
  })
}

// 页面初始化
onMounted(async () => {
  // 设置路由变化监听
  setupRouteWatcher();
  
  // 检查是否是游客模式
  const isGuestMode = uni.getStorageSync('isGuestMode')
  
  if (isGuestMode) {
    // 游客模式直接使用默认游客信息
    loading.value = false
    return
  }
  
  // 非游客模式才检查登录状态
  const tokenValue = token.getToken()
  if (!tokenValue) {
    uni.navigateTo({ url: '/pages/login/account-login' })
    return
  }
  
  try {
    await fetchUserData()
    await fetchTokenUsage()
    // 设置登录状态变化监听
    setupLoginListener()
  } catch (error) {
    console.error('初始化失败:', error)
    uni.showToast({
      title: '获取数据失败，请重试',
      icon: 'none'
    })
  } finally {
    loading.value = false
  }
})

// 组件卸载时移除事件监听
onUnmounted(() => {
  uni.$off('loginStateChanged')
})

const fetchUserData = async () => {
  try {
    // Clear cache to ensure getting latest data
    userStore.lastRefreshTime = 0
    
    // Get user info with retry
    let attempts = 0;
    const maxAttempts = 2;
    let userRes = null;
    
    while (attempts < maxAttempts) {
      try {
        userRes = await api.user.getUserInfo();
        if (userRes?.data) break;
      } catch (err) {
        console.log(`Attempt ${attempts + 1} failed: ${err.message}`);
        // Wait a bit before retrying
        await new Promise(resolve => setTimeout(resolve, 1000));
      }
      attempts++;
    }
    
    // If we got user data, use it
    if (userRes?.data) {
      userStore.setUserInfo(userRes.data)
      
      // If VIP user, get membership info
      if (userRes.data.vipStatus === 1) {
        await fetchVipInfo()
      }
    } else {
      // If all attempts failed, switch to guest mode
      console.warn('Failed to get user info after multiple attempts, switching to guest mode');
      userStore.setGuestMode();
    }
  } catch (error) {
    console.error('Getting user data failed:', error)
    // Switch to guest mode on persistent errors
    userStore.setGuestMode();
    throw error
  }
}

// 获取Token使用情况
const fetchTokenUsage = async () => {
  try {
    const res = await api.user.getDailyTokenUsage()
    
    if (res?.data) {
      // 更新用户信息中的token数据
      if (userStore.userInfo) {
        userStore.userInfo.totalTokensUsed = res.data.totalTokensUsed || 0
        userStore.userInfo.totalTokensBalance = res.data.totalTokensBalance || 0
        
        // 触发视图更新
        userStore.setUserInfo({...userStore.userInfo})
      }
    }
  } catch (error) {
    console.error('获取Token使用情况失败:', error)
    throw error
  }
}

// 获取会员信息
const fetchVipInfo = async () => {
  try {
    let vipData = null
    
    // 尝试从API获取
    const res = await api.user.getVipInfo()
    if (res?.data) {
      vipData = res.data
      vipInfo.value = vipData
    }
  } catch (error) {
    console.error('获取会员信息失败:', error)
  }
}

// 刷新Token使用情况
const refreshTokenUsage = async () => {
  try {
    uni.showLoading({ title: '刷新中...', mask: true })
    
    await fetchTokenUsage()
    
    uni.showToast({ title: '刷新成功', icon: 'success' })
  } catch (error) {
    uni.showToast({ title: '刷新失败', icon: 'none' })
  } finally {
    uni.hideLoading()
  }
}

// 昵称编辑相关方法
const startEditingNickname = () => {
  // 优先使用 nickname，如果没有，再使用 username
  tempNickname.value = userInfo.value.nickname || userInfo.value.username
  isEditingNickname.value = true
}

const saveNickname = async () => {
  // 去除首尾空格
  const newNickname = tempNickname.value.trim()
  
  // 检查昵称是否为空或未改变
  if (!newNickname || newNickname === userInfo.value.nickname) {
    isEditingNickname.value = false
    return
  }

  // 昵称长度验证
  if (newNickname.length < 2 || newNickname.length > 12) {
    uni.showToast({
      title: '昵称长度应在2-12个字符之间',
      icon: 'none',
      duration: 2000
    })
    return
  }

  try {
    uni.showLoading({ 
      title: '保存中...', 
      mask: true 
    })
    
    // 直接调用API更新
    const res = await api.user.updateUserInfo({ 
      nickname: newNickname 
    })

    // 检查响应
    if (res.success) {
      // 更新本地用户信息
      userStore.setUserInfo({
        ...userInfo.value,
        nickname: newNickname
      })

      uni.showToast({ 
        title: '昵称更新成功', 
        icon: 'success',
        duration: 1500
      })
    } else {
      throw new Error(res.message || '更新昵称失败')
    }
  } catch (error) {
    console.error('更新昵称失败:', error)
    
    uni.showToast({
      title: error.message || '更新昵称失败',
      icon: 'none',
      duration: 3000
    })
  } finally {
    isEditingNickname.value = false
    uni.hideLoading()
  }
}

// 邮箱编辑相关方法
const startEditingEmail = () => {
  tempEmail.value = userInfo.value.email
  isEditingEmail.value = true
}

const saveEmail = async () => {
  if (!tempEmail.value || tempEmail.value === userInfo.value.email) {
    isEditingEmail.value = false
    return
  }
  
  // 验证邮箱格式
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  if (!emailRegex.test(tempEmail.value)) {
    uni.showToast({
      title: '邮箱格式不正确',
      icon: 'none'
    })
    return
  }

  try {
    uni.showLoading({ title: '保存中...', mask: true })
    
    // 更新邮箱
    const res = await api.user.updateUserInfo({ email: tempEmail.value })

    // 检查响应
    if (res.success) {
      // 并行获取最新用户信息和Token使用情况
      const [userInfoRes, tokenUsageRes] = await Promise.all([
        api.user.getUserInfo(),
        api.user.getDailyTokenUsage()
      ])
      
      // 合并用户信息和Token数据
      const mergedUserInfo = {
        ...userInfoRes.data,
        totalTokensUsed: tokenUsageRes.data?.totalTokensUsed || userInfoRes.data.totalTokensUsed || 0,
        totalTokensBalance: tokenUsageRes.data?.totalTokensBalance || userInfoRes.data.totalTokensBalance || 0
      }
      
      // 更新本地用户信息
      userStore.setUserInfo(mergedUserInfo)

      uni.showToast({ 
        title: '邮箱更新成功', 
        icon: 'success' 
      })
    } else {
      throw new Error(res.message || '更新邮箱失败')
    }
  } catch (error) {
    console.error('更新邮箱失败:', error)
    uni.showToast({
      title: error.message || '更新邮箱失败',
      icon: 'none'
    })
  } finally {
    isEditingEmail.value = false
    uni.hideLoading()
  }
}

// 完整刷新页面数据
const refreshAllPageData = async () => {
  try {
    loading.value = true
    uni.showLoading({ title: '刷新中...', mask: true })
    
    // 清除缓存，确保获取最新数据
    userStore.lastRefreshTime = 0
    
    // 并行请求所有数据
    await Promise.all([
      fetchUserData(),
      fetchTokenUsage()
    ])
    
    uni.showToast({ title: '刷新成功', icon: 'success' })
  } catch (error) {
    console.error('刷新页面数据失败:', error)
    uni.showToast({ title: '刷新失败', icon: 'none' })
  } finally {
    loading.value = false
    uni.hideLoading()
  }
}

const onChooseAvatar = async (e) => {
  try {
    // 检查头像选择是否有效
    if (!e?.detail?.avatarUrl) {
      uni.showToast({ 
        title: '选择头像失败', 
        icon: 'none' 
      })
      return
    }
    
    // 显示加载状态
    uni.showLoading({ 
      title: '更新头像中...', 
      mask: true 
    })
    
    const avatarUrl = e.detail.avatarUrl
    let tempFilePath = avatarUrl
    
    // 处理不同来源的头像文件
    if (!avatarUrl.startsWith('wxfile://') && !avatarUrl.startsWith('http://tmp/')) {
      const downloadRes = await new Promise((resolve, reject) => {
        uni.downloadFile({
          url: avatarUrl,
          success: res => res.statusCode === 200 ? resolve(res) : reject(new Error('下载失败')),
          fail: reject
        })
      })
      
      tempFilePath = downloadRes.tempFilePath
    }
    
    // 获取并验证当前登录凭证
    const currentToken = token.getToken()
    if (!currentToken) {
      throw new Error('登录已过期，请重新登录')
    }
    
    // 上传头像
    const userId = uni.getStorageSync('userId')
    
    const uploadResult = await new Promise((resolve, reject) => {
      uni.uploadFile({
        // url: 'https://gushu.szxhdkj.com/file/avatar',
		url: 'https://gushu.szxhdkj.com/file/avatar',
        filePath: tempFilePath,
        name: 'file',
        formData: { userId },
        header: {
          'Authorization': 'Bearer ' + currentToken
        },
        success: res => {
          try {
            if (res.statusCode !== 200) {
              return reject(new Error(`上传失败，状态码: ${res.statusCode}`))
            }
            
            const responseData = JSON.parse(res.data)
            if (!responseData.success) {
              return reject(new Error(`上传失败: ${responseData.message || '未知错误'}`))
            }
            
            resolve(responseData)
          } catch (err) {
            reject(new Error(`解析响应失败: ${err.message}`))
          }
        },
        fail: err => reject(err)
      })
    })
    
    // 验证上传结果
    if (!uploadResult.data?.url) {
      throw new Error('上传成功但未返回有效的URL')
    }
    
    // 更新用户头像信息
    const updateRes = await userStore.updateUserInfo({ 
      avatar: uploadResult.data.url 
    })
    
    // 并行获取最新用户信息和Token使用情况
    const [userInfoRes, tokenUsageRes] = await Promise.all([
      api.user.getUserInfo(),
      api.user.getDailyTokenUsage()
    ])
    
    // 合并用户信息和Token数据
    const mergedUserInfo = {
      ...userInfoRes.data,
      totalTokensUsed: tokenUsageRes.data?.totalTokensUsed || userInfoRes.data.totalTokensUsed || 0,
      totalTokensBalance: tokenUsageRes.data?.totalTokensBalance || userInfoRes.data.totalTokensBalance || 0
    }
    
    // 更新本地用户信息
    userStore.setUserInfo(mergedUserInfo)
    
    // 显示成功提示
    uni.showToast({ 
      title: '头像更新成功', 
      icon: 'success' 
    })
    
  } catch (error) {
    console.error('更新头像失败:', error)
    
    // 处理登录过期情况
    if (error.message && (error.message.includes('401') || error.message.includes('登录已过期'))) {
      try {
        const refreshResult = await userStore.refreshToken()
        if (refreshResult) {
          uni.showToast({
            title: 'token已刷新，请重试',
            icon: 'none',
            duration: 2000
          })
          return
        }
      } catch (refreshError) {
        console.error('刷新token失败:', refreshError)
      }
    }
    
    // 显示错误提示
    uni.showToast({ 
      title: '更新头像失败: ' + (error.message || '未知错误'),
      icon: 'none',
      duration: 3000
    })
  } finally {
    // 确保隐藏加载状态
    uni.hideLoading()
  }
}

// 复制UUID
const copyUUID = () => {
  if (!userInfo.value.uuid) return
  
  uni.setClipboardData({
    data: userInfo.value.uuid,
    success: () => {
      uni.showToast({
        title: 'UUID已复制',
        icon: 'success'
      })
    }
  })
}

// 绑定手机号
const bindPhone = () => {
  uni.navigateTo({ url: '/pages/user/bind-phone' })
}

// 绑定邮箱
const bindEmail = () => {
  tempEmail.value = ''
  isEditingEmail.value = true
}

// 格式化函数
const formatPhone = (phone) => {
  if (!phone) return ''
  return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}

const formatUUID = (uuid) => {
  if (!uuid) return ''
  return `${uuid.substring(0, 8)}...${uuid.substring(uuid.length - 8)}`
}

const formatDate = (dateStr) => {
  if (!dateStr) return ''
  
  const date = new Date(dateStr)
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  
  return `${year}-${month}-${day}`
}

const formatNumber = (num) => {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

// 退出登录
const handleLogout = () => {
  uni.showModal({
    title: '提示',
    content: '确定要退出登录吗？',
    success: async (res) => {
      if (res.confirm) {
        try {
          await userStore.logout()
          
          // 清除所有刷新标记
          uni.setStorageSync('needDataRefresh', 'false');
          uni.removeStorageSync('refreshed_pages/my/my');
          uni.removeStorageSync('refreshed_pages/index/index');
          uni.removeStorageSync('refreshed_pages/discover/discover');
          uni.removeStorageSync('refreshed_pages/device-manage/device-manage');
          
          setTimeout(() => {
            uni.navigateTo({ url: '/pages/login/account-login' })
          }, 500)
        } catch (error) {
          console.error('退出登录失败:', error)
          uni.showToast({
            title: '退出失败',
            icon: 'none'
          })
        }
      }
    }
  })
}

// 页面导航
const goBack = () => {
  uni.navigateBack()
}

const goToMemberCenter = () => {
  uni.navigateTo({ url: '/pages/membership/membership' })
}

// 小程序支付正确调用方式
const handlePay = async () => {
  if (isPayLoading.value) return;
  
  isPayLoading.value = true;
  
  try {
    // 获取token
    const token = uni.getStorageSync('token');
    if (!token) {
      throw new Error('登录状态失效，请重新登录');
    }
    
    console.log('准备支付订单:', orderId.value, '类型:', orderType.value);
    
    // 构建支付参数
    const payParams = {
      orderId: orderId.value,
      orderType: orderType.value === 'vip' ? 'VIP' : 'PRODUCT',
      payMethod: 'wxpay',
      tradeType: 'JSAPI' // 小程序支付使用JSAPI类型
    };
    
    console.log('小程序支付请求参数:', payParams);
    
    // 调用后端接口获取支付参数
    const res = await api.payment.createOrder(payParams, {
      headers: { 'Authorization': 'Bearer ' + token }
    });
    
    if (res && res.code === 200 && res.data) {
      console.log('支付返回数据:', res.data);
      
      // 注意：这里接收的字段名可能根据后端返回有所不同
      // 确保收到的是10位数字的时间戳（秒级）
      const payData = res.data;
      
      // 调用支付API
      uni.requestPayment({
        provider: 'wxpay',
        timeStamp: payData.timeStamp,
        nonceStr: payData.nonceStr,
        package: payData.package || `prepay_id=${payData.prepayId}`, // 注意格式
        signType: 'RSA', // 新版固定为RSA
        paySign: payData.paySign,
        success: (res) => {
          console.log('支付成功:', res);
          showPaymentResult(true, '支付成功');
          fetchOrderInfo();
          refreshUserInfo();
        },
        fail: (err) => {
          console.error('支付失败:', err);
          if (err.errMsg.indexOf('cancel') !== -1) {
            showPaymentResult(false, '支付已取消');
          } else {
            showPaymentResult(false, '支付失败，请重试');
          }
        },
        complete: () => {
          isPayLoading.value = false;
        }
      });
    } else {
      throw new Error(res?.message || '创建支付订单失败');
    }
  } catch (error) {
    console.error('支付过程出错:', error);
    uni.showToast({
      title: error.message || '支付失败，请重试',
      icon: 'none'
    });
    isPayLoading.value = false;
  }
};
</script>

<!-- 样式部分 -->
<style lang="scss">
.page-container {
  min-height: 100vh;
  background-color: #F5F5F5;
  padding-bottom: 180rpx; /* 增加底部padding，为TabBar和安全区域留出足够空间 */
  
  .nav-bar {
    height: 88rpx;
    background: #fff;
    display: flex;
    align-items: center;
    padding: 0 30rpx;
    border-bottom: 1px solid #f5f5f5;
    position: relative;
    box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
    
    .back-button {
      position: absolute;
      left: 30rpx;
      font-size: 40rpx;
      color: #333;
      z-index: 10;
    }
    
    .title {
      width: 100%;
      text-align: center;
      font-size: 36rpx;
      font-weight: 600;
      color: #333;
    }
  }
  
  .loading-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 300rpx;
    
    .loading-spinner {
      width: 60rpx;
      height: 60rpx;
      border: 4rpx solid #f3f3f3;
      border-top: 4rpx solid #007AFF;
      border-radius: 50%;
      animation: spin 1s linear infinite;
      margin-bottom: 20rpx;
    }
    
    .loading-text {
      font-size: 28rpx;
      color: #999;
    }
    
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
  }
  
  .user-info {
    height: 420rpx;
    background: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin-bottom: 20rpx;
    position: relative;
    overflow: hidden;
    
        .decoration-bg {
              position: absolute;
              top: 0;
              left: 0;
              right: 0;
              height: 260rpx;
              background: linear-gradient(135deg, #5677fc, #38a0ff);
              z-index: 0;
              border-bottom-left-radius: 40rpx;
              border-bottom-right-radius: 40rpx;
              box-shadow: 0 4rpx 20rpx rgba(56, 160, 255, 0.3);
      
      &::after {
        content: '';
        position: absolute;
        bottom: -20rpx;
        left: 50%;
        transform: translateX(-50%);
        width: 120rpx;
        height: 6rpx;
        background: rgba(255, 255, 255, 0.6);
        border-radius: 3rpx;
      }
    }
    
    .avatar-button {
      padding: 0;
      width: 180rpx !important;
      height: 180rpx !important;
      margin-bottom: 30rpx;
      background: none;
      border: none;
      position: relative;
      z-index: 1;
      box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.15);
      border-radius: 50%;
      transition: all 0.3s ease;
      
      &::after {
        border: none;
      }
      
      &:active {
        transform: scale(0.95);
      }
    }
    
    .avatar {
      width: 180rpx;
      height: 180rpx;
      border-radius: 50%;
      border: 4rpx solid #fff;
    }
    
    .nickname-container {
      margin-bottom: 16rpx;
      position: relative;
      z-index: 1;
      padding: 8rpx 20rpx;
      border-radius: 30rpx;
      background: rgba(255, 255, 255, 0.9);
      box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
      transition: all 0.3s ease;
      
      &:active {
        transform: scale(0.98);
        background: rgba(255, 255, 255, 1);
      }
    }
    
    .nickname {
      font-size: 40rpx;
      font-weight: 600;
      color: #333;
      text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.05);
    }
    
    .nickname-input {
      font-size: 40rpx;
      font-weight: 500;
      text-align: center;
      width: 400rpx;
      padding: 10rpx;
    }
    
    .new-vip-card {
      margin: 16rpx 20rpx;
      padding: 0 20rpx;
      background: linear-gradient(90deg, #ffe082 0%, #ffd54f 100%);
      border-radius: 10rpx;
      height: 80rpx;
      display: flex;
      align-items: center;
      justify-content: space-between;
      box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.1);
      width: calc(95% - 40rpx);
      
      .left-section {
        display: flex;
        align-items: center;
        height: 100%;
        
        .icon-container {
          display: flex;
          align-items: center;
          margin-right: 16rpx;
          
          .vip-icon {
            width: 38rpx;
            height: 38rpx;
          }
        }
        
        .text-content {
          display: flex;
          flex-direction: column;
          justify-content: center;
          
          .main-title {
            font-size: 28rpx;
            color: #b28704;
            font-weight: bold;
            line-height: 1.2;
          }
          
          .sub-title {
            font-size: 24rpx;
            color: #b28704;
            line-height: 1.2;
          }
        }
      }
      
      .right-section {
        .action-button {
          display: block;
          font-size: 26rpx;
          color: #ff4d4f;
          background-color: rgba(255, 255, 255, 0.4);
          padding: 4rpx 16rpx;
          border-radius: 10rpx;
          font-weight: bold;
          white-space: nowrap;
          text-align: center;
        }
      }
    }
  }
  
  .section-title {
    font-size: 32rpx;
    font-weight: 500;
    color: #333;
    padding: 30rpx;
    display: flex;
    justify-content: space-between;
    align-items: center;
    
    .refresh-btn {
      font-size: 26rpx;
      color: #5677fc;
      font-weight: normal;
    }
  }
  
  .info-section, .token-section, .vip-section {
    background: #fff;
    margin: 0 20rpx 20rpx;
    border-radius: 16rpx;
    overflow: hidden;
    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
    transition: all 0.3s ease;
    
    &:active {
      transform: scale(0.98);
    }
  }
  
  .token-section {
    position: relative;
    overflow: hidden;
    
    .decoration-bg {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 100%;
      background: linear-gradient(135deg, #5677fc, #38a0ff);
      z-index: 0;
      border-radius: 16rpx;
      box-shadow: 0 4rpx 20rpx rgba(56, 160, 255, 0.3);
    }
    
    .section-title, .token-card, .token-progress {
      position: relative;
      z-index: 1;
    }
    
    .section-title {
      color: #fff;
      font-weight: 600;
      text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.1);
      
      .refresh-btn {
        color: #fff;
        background: rgba(255, 255, 255, 0.2);
        padding: 4rpx 16rpx;
        border-radius: 30rpx;
        font-size: 24rpx;
        transition: all 0.2s ease;
        
        &:active {
          background: rgba(255, 255, 255, 0.3);
          transform: scale(0.95);
        }
      }
    }
  }
  
  .info-list {
    .info-item {
      display: flex;
      padding: 32rpx 30rpx;
      border-bottom: 1rpx solid rgba(245, 245, 245, 0.6);
      align-items: center;
      transition: background-color 0.2s ease;
      
      &:active {
        background-color: #f9f9f9;
      }
      
      &:last-child {
        border-bottom: none;
      }
      
      .label {
        width: 160rpx;
        font-size: 28rpx;
        color: #666;
        font-weight: 500;
      }
      
      .value {
        flex: 1;
        font-size: 28rpx;
        color: #333;
      }
      
      .email-container {
        flex: 1;
        padding: 6rpx 0;
        transition: all 0.2s ease;
        
        &:active {
          opacity: 0.8;
        }
      }
      
      .email-input {
        flex: 1;
        font-size: 28rpx;
        color: #333;
        background: #f8f8f8;
        padding: 8rpx 16rpx;
        border-radius: 6rpx;
        border: 1px solid #eee;
      }
      
      .value-with-copy {
        flex: 1;
        display: flex;
        justify-content: space-between;
        align-items: center;
        
        .uuid {
          font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
          letter-spacing: 0;
          font-size: 28rpx;
          color: #333;
          background: #f8f8f8;
          padding: 8rpx 16rpx;
          border-radius: 6rpx;
        }
        
        .copy-btn {
          font-size: 24rpx;
          color: #fff;
          padding: 6rpx 16rpx;
          background: #5677fc;
          border-radius: 30rpx;
          box-shadow: 0 2rpx 8rpx rgba(86, 119, 252, 0.3);
          transition: all 0.2s ease;
          
          &:active {
            transform: scale(0.95);
            opacity: 0.9;
          }
        }
      }
      
      .action {
        font-size: 26rpx;
        color: #5677fc;
        margin-left: 20rpx;
        padding: 6rpx 16rpx;
        background: rgba(86, 119, 252, 0.1);
        border-radius: 30rpx;
        transition: all 0.2s ease;
        
        &:active {
          transform: scale(0.95);
          background: rgba(86, 119, 252, 0.2);
        }
      }
    }
  }
  
  .token-card {
    display: flex;
    padding: 0 30rpx 30rpx;
    
    .token-item {
      flex: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      position: relative;
      padding: 16rpx 0;
      
      &:not(:last-child):after {
        content: '';
        position: absolute;
        right: 0;
        top: 20%;
        height: 60%;
        width: 1rpx;
        background: rgba(255, 255, 255, 0.3);
      }
      
      .token-label {
        font-size: 26rpx;
        color: rgba(255, 255, 255, 0.9);
        margin-bottom: 16rpx;
      }
      
      .token-value {
        font-size: 36rpx;
        color: #fff;
        font-weight: 600;
        text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
      }
    }
  }
  
  .token-progress {
    padding: 0 30rpx 30rpx;
    display: flex;
    align-items: center;
    
    .progress-bar {
      flex: 1;
      height: 20rpx;
      background: rgba(255, 255, 255, 0.3);
      border-radius: 10rpx;
      overflow: hidden;
      margin-right: 20rpx;
      box-shadow: inset 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
      
      .progress-inner {
        height: 100%;
        background: #fff;
        border-radius: 10rpx;
        box-shadow: 0 0 8rpx rgba(255, 255, 255, 0.5);
        transition: width 0.5s ease-out;
      }
    }
    
    .progress-text {
      font-size: 28rpx;
      color: #fff;
      width: 70rpx;
      text-align: right;
      font-weight: 600;
      text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.1);
    }
  }
  
  .vip-card {
    padding: 0 30rpx 30rpx;
    background: linear-gradient(to right, rgba(255, 215, 0, 0.05), rgba(255, 215, 0, 0.1));
    border-radius: 12rpx;
    margin: 0 20rpx 20rpx;
    
    .vip-info {
      display: flex;
      justify-content: space-between;
      margin-bottom: 20rpx;
      padding: 16rpx 0;
      border-bottom: 1rpx dashed rgba(255, 215, 0, 0.3);
      
      &:last-child {
        margin-bottom: 0;
        border-bottom: none;
      }
      
      .vip-label {
        font-size: 28rpx;
        color: #666;
        font-weight: 500;
      }
      
      .vip-value {
        font-size: 28rpx;
        color: #333;
        font-weight: 600;
        background: linear-gradient(to right, #FFD700, #FFA500);
        -webkit-background-clip: text;
        color: transparent;
        padding: 0 10rpx;
      }
    }
  }
  
  .logout-button {
    width: 90%;
    height: 88rpx;
    margin: 40rpx auto;
    background: #fff;
    color: #FF4D4F;
    font-size: 32rpx;
    font-weight: 500;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 44rpx;
    border: none;
    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
    transition: all 0.3s ease;
    position: relative;
    overflow: hidden;
    
    &::before {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: linear-gradient(to right, rgba(255, 77, 79, 0.05), rgba(255, 77, 79, 0.1), rgba(255, 77, 79, 0.05));
      opacity: 0;
      transition: opacity 0.3s ease;
    }
    
    &:active {
      transform: scale(0.98);
      box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
      
      &::before {
        opacity: 1;
      }
    }
    
    &::after {
      border: none;
    }
  }
}

.fixed-footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
  background-color: #fff;
  box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
}
</style>